﻿namespace BM.Tools.WebControls.MForm.Controls.Modifiers
{
    using System;
    using System.Linq;
    using System.Web.UI;

    using BM.Tools.WebControls.MForm.Controls.Items;
    using BM.Tools.WebControls.MForm.Navigation;

    /// <summary>
    /// <para>
    /// This modifier may attach the same addition to any offspring 
    /// that is selected with a certain path.
    /// </para>
    /// <para>
    /// This way it is easy to avoid repeating code in aspx.
    /// </para>
    /// </summary>
    public class AdditionsAttacher : OffspringsOwnerModifier
    {
        /// <summary>
        /// the offspring type
        /// </summary>
        private OffspringType filter = OffspringType.Offspring;

        /// <summary>
        /// Gets or sets AdditionsTemplate.
        /// </summary>        
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate AdditionsTemplate
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets Filter.
        /// </summary>        
        public OffspringType Filter
        {
            get
            {
                return filter;
            }

            set
            {
                filter = value;
            }
        }

        /// <summary>
        /// Gets or sets SelectorPath.
        /// </summary>        
        public string SelectorPath
        {
            get;
            set;
        }

        /// <summary>
        /// Performs attaching.
        /// </summary>
        /// <param name="offspringItem">
        /// The offspring item.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected override void OnItemLoad(OffspringsOwnerItem offspringItem, EventArgs e)
        {
            PerformAttaching(offspringItem);            
            offspringItem.Basis.DataBound += PerformAttachingAfterDataBind(offspringItem);
        }

        /// <summary>
        /// Attaches all the additions from the template to the item
        /// </summary>
        /// <param name="result">
        /// The result.
        /// </param>
        private void AttachAdditions(OffspringItem result)
        {
            AdditionsTemplate.InstantiateIn(result.Additions);
        }

        private EventHandler PerformAttachingAfterDataBind(OffspringsOwnerItem item)
        {
            return (sender, args) => PerformAttaching(item);
        }

        private void PerformAttaching(OffspringsOwnerItem item)
        {
            item.Select(SelectorPath).FilterType(Filter).ToList().ForEach(AttachAdditions);
        }
    }
}